#include <Ethernet.h>
#include <SPI.h>
#include "Arduino.h"
#include "board.h"
#include "matrixLCD.h"
#include "getBoard.h"
#include "arduinoPins.h"
#include "inCheck.h"

#define PACKETSIZE 36


Square board[10][10]; //main chessboard
//bool status_board[8][8]; //boolean array used by MUX array 
Square *whiteKing;
Square *blackKing;
State game_state = GAMENOTSTARTED;
int NUM_PIECES_LEFT;

byte server[] = { 192,168,1,1 }; //ip Address of the server you will connect to
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x53, 0x36 }; //mac address of Ethernet Shield 
byte ip[] = {192, 168, 1, 2}; //ip
EthernetClient client;
int this_move, temp, srow, scol, drow, dcol;
Move my_move;
int button;

void setup()
{
  pinMode(IN_A1, INPUT);//mux inputs
  pinMode(IN_B1, INPUT);
  pinMode(IN_C1, INPUT);
  pinMode(IN_D1, INPUT);
  pinMode(IN_E1, INPUT);
  pinMode(IN_F1, INPUT);
  pinMode(IN_G1, INPUT);
  pinMode(IN_H1, INPUT);
  pinMode(IN_A2, INPUT);
  pinMode(IN_B2, INPUT);
  pinMode(IN_C2, INPUT);
  pinMode(IN_D2, INPUT);
  pinMode(IN_E2, INPUT);
  pinMode(IN_F2, INPUT);
  pinMode(IN_G2, INPUT);
  pinMode(IN_H2, INPUT);

  pinMode(SEL_A, OUTPUT);//mux select lines
  pinMode(SEL_B, OUTPUT);
  
  pinMode(DIR_PIN_A, OUTPUT);
  pinMode(STEP_PIN_A, OUTPUT);
  
  pinMode(DIR_PIN_B, OUTPUT);
  pinMode(STEP_PIN_B, OUTPUT);
  
  pinMode(MAGNET, OUTPUT);
  
  //Ethernet.begin(mac, ip);
  Serial.begin(9600);
  initLCD();
  clearLCD();
  
  //connect2server(); //Connecting to server
  
  /*
  initLCD();
  introLCD();
  delay(1000);
  getPromotionChoice(WHITE);*/
}

void loop()
{
  Square src = {QUEEN, BLACK, 1, 15, true, false, true};
  Square dest = {KING, WHITE, 1, 1, true, true, false};
  Square dest2 = {KING, BLACK, 2, 1, true, true, false};
  
  while(1) {
    update_board(src, dest);
    update_board(dest, src);
    continue;
    
    update_board(src, dest2);
    Serial1.read();
    digitalWrite(MAGNET, HIGH);
    update_board(src, dest);
    digitalWrite(MAGNET, LOW);
    update_board(dest, src);
  }
}

void connect2server() {
  
  while (1) {
    Serial.println("Connecting.."); 
    if (client.connect(server, 3490)) {
      Serial.println("Connection Established!");
      break;
    }
    else {
      Serial.println("Could not connect! Re-trying after 1.5 seconds");
      delay(1500);
    }
  }
}

int castle_handler(int this_move, Color color) {
  
    if (!is_legal_castling(this_move, color)) //check if legal castling  
        return 0;
        
    int king = abs(this_move)/10000;
    int k_srow = king/1000;
    int k_scol = (king/100)%10;
    int k_drow = (king%100)/10;
    int k_dcol = king%10;
    
    my_move = (Move){board[k_srow + 1][k_scol + 1], board[k_drow + 1][k_dcol + 1], CASTLING};
    update_local_board(&my_move, WHITE); //update 2-d baord array
    //send(&my_move);//send move to server
    
    return 1;
}


int enpassant_handler(int this_move, Color color) {
  
    int srow = (this_move%1000000)/100000; //source row
    int scol = ((this_move%1000000)/10000)%10; //source col
    int drow = (this_move%10000)/1000; //dest row
    int dcol = ((this_move%10000)/100)%10;//dest col
    
    int cap_row = (this_move%100)/10; //captured piece row
    int cap_col = this_move%10; //captured piece col
        
    if( !check_en_passant(this_move, WHITE) || !is_legal_move(&board[srow + 1][scol + 1], &board[drow + 1][dcol + 1]) ) 
        return 0;
       
    my_move = (Move){board[srow + 1][scol + 1], board[drow + 1][dcol + 1], ENPASSANT};
    update_local_board(&my_move, WHITE); //update 2-d baord array
    //send(&my_move); //send move to server

    return 1;
}


int all_other_moves_handler(int this_move, Color color) {

    int srow = this_move/1000;
    int scol = (this_move/100)%10;
    int drow = (this_move%100)/10;   
    int dcol = this_move%10;
    
    if(!is_legal_move(&board[srow + 1][scol + 1], &board[drow + 1][dcol + 1])) 
        return 0;
    
    if(srow == 1 && drow == 0 && board[srow][scol].type == PAWN) {
        board[drow + 1][dcol + 1].type = getPromotionChoice(WHITE);
        my_move = (Move){board[srow + 1][scol + 1], board[drow + 1][dcol + 1], PROMOTION};
    }
    else
        my_move = (Move){board[srow + 1][scol + 1], board[drow + 1][dcol + 1], NEWMOVE};
    
    update_local_board(&my_move, WHITE); //update 2-d baord array
    //send(&my_move); //send move to server
    
    return 1;
}
  
    

/*Send data to server */
void send(Move *move_pkt) {
  
  char writebuf[PACKETSIZE + 1];
  writebuf[PACKETSIZE] = '\0';
   
  memcpy(writebuf, move_pkt, PACKETSIZE);
  for(int i = 0; i < PACKETSIZE; i++) 
    client.write(writebuf[i]);
}

/*Recieve data from server*/
void recv(Move *move_pkt) {
  
  char readbuf[PACKETSIZE + 1];
  int pos = 0;
  while ( pos < PACKETSIZE ) {
    if(client.available())
      readbuf[pos] = client.read();
  }
  memcpy(move_pkt, readbuf, PACKETSIZE);
}
  
  
  

